
#include	"mb.h"


#include	"port.h"
#include	"mbconfig.h"
#include	"mbproto.h"
#include	"mbfunc.h"

#include	"main.h"
#include	"stdint.h"

//输入寄存器起始地址
#define REG_INPUT_START 0x0000

//输入寄存器数量
#define REG_INPUT_NREGS 	512

//保持寄存器起始地址
#define REG_HOLDING_START 0x1000

//保持寄存器数量
#define REG_HOLDING_NREGS 	256

//线圈起始地址
#define REG_COILS_START 0x2000

//线圈数量
#define REG_COILS_SIZE 16

//开关寄存器起始地址
#define REG_DISCRETE_START 0x3000

//开关寄存器数量
#define REG_DISCRETE_SIZE 16


uint16_t	usRegHoldingStart	= REG_HOLDING_START;
uint16_t	usRegInputStart = REG_INPUT_START;

uint16_t	usRegHoldingBuf[REG_HOLDING_NREGS] = {0};
uint16_t	usRegInputBuf[REG_INPUT_NREGS] = {0};


#define		MB_TEST_SPAN	1000
void	mb_input_reg_val_test(void)
{
	static	uint32_t	mb_test_stamp;
	static	uint16_t	mb_test_cnt;
	int16_t		i;
	if(HAL_GetTick()-mb_test_stamp >= MB_TEST_SPAN)
	{
		mb_test_stamp = HAL_GetTick();

		mb_test_cnt ++;
		for(i=0;i<64;i++)
		{
			usRegInputBuf[i] = i + mb_test_cnt;
		}

	}
}


//int main(void)
//{
//		usRegInputBuf[0] = 'I';
//		usRegInputBuf[1] = ' ';
//		usRegInputBuf[2] = 'a';
//		usRegInputBuf[3] = 'm';
//		usRegInputBuf[4] = ' ';
//		usRegInputBuf[5] = 'I';
//
//
//		RCC_Config();
//		eMBInit(MB_RTU, 0x01, 0x01, 9600, MB_PAR_NONE);
//		eMBEnable();
//		for(;;)
//		{
//			(void)eMBPoll();
//		}
//}

//static void Delay(__IO uint32_t nCount)	 //简单的延时函数
//{
//	for(; nCount != 0; nCount--);
//}
/*********************************************END OF FILE**********************/

/****************************************************************************
* 名	  称：eMBRegInputCB
* 功    能：读取输入寄存器，对应功能码是 04 eMBFuncReadInputRegister
* 入口参数：pucRegBuffer: 数据缓存区，用于响应主机
*						usAddress: 寄存器地址
*						usNRegs: 要读取的寄存器个数
* 出口参数：
* 注	  意：上位机发来的 帧格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
*								+StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
*								+LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
*								+CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
*							3 区
****************************************************************************/
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

/****************************************************************************
* 名	  称：eMBRegHoldingCB
* 功    能：对应功能码有：06 写保持寄存器 eMBFuncWriteHoldingRegister
*													16 写多个保持寄存器 eMBFuncWriteMultipleHoldingRegister
*													03 读保持寄存器 eMBFuncReadHoldingRegister
*													23 读写多个保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
* 入口参数：pucRegBuffer: 数据缓存区，用于响应主机
*						usAddress: 寄存器地址
*						usNRegs: 要读写的寄存器个数
*						eMode: 功能码
* 出口参数：
* 注	  意：4 区
****************************************************************************/
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
	eMBErrorCode    eStatus = MB_ENOERR;
	int             iRegIndex;


	if((usAddress >= REG_HOLDING_START)&&\
		((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))
	{
		iRegIndex = (int)(usAddress - usRegHoldingStart);
		switch(eMode)
		{
			case MB_REG_READ://读 MB_REG_READ = 0
        while(usNRegs > 0)
				{
					*pucRegBuffer++ = (uint8_t)(usRegHoldingBuf[iRegIndex] >> 8);
					*pucRegBuffer++ = (uint8_t)(usRegHoldingBuf[iRegIndex] & 0xFF);
          iRegIndex++;
          usNRegs--;
				}
        break;
			case MB_REG_WRITE://写 MB_REG_WRITE = 0
				while(usNRegs > 0)
				{
					usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
          usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
          iRegIndex++;
          usNRegs--;
        }
			}
	}
	else//错误
	{
		eStatus = MB_ENOREG;
	}

	return eStatus;
}

/****************************************************************************
* 名	  称：eMBRegCoilsCB
* 功    能：对应功能码有：01 读线圈 eMBFuncReadCoils
*													05 写线圈 eMBFuncWriteCoil
*													15 写多个线圈 eMBFuncWriteMultipleCoils
* 入口参数：pucRegBuffer: 数据缓存区，用于响应主机
*						usAddress: 线圈地址
*						usNCoils: 要读写的线圈个数
*						eMode: 功能码
* 出口参数：
* 注	  意：如继电器
*						0 区
****************************************************************************/
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
	eMBErrorCode    eStatus = MB_ENOERR;
	int             iRegIndex;


	if((usAddress >= REG_HOLDING_START)&&\
		((usAddress+usNCoils) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))
	{
		iRegIndex = (int)(usAddress - usRegHoldingStart);
		switch(eMode)
		{
			case MB_REG_READ://读 MB_REG_READ = 0
        while(usNCoils > 0)
				{
// 					*pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);
// 					*pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF);
          iRegIndex++;
          usNCoils--;
				}
        break;
			case MB_REG_WRITE://写 MB_REG_WRITE = 1
				while(usNCoils > 0)
				{
// 					usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
//           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
          iRegIndex++;
          usNCoils--;
        }
			}
	}
	else//错误
	{
		eStatus = MB_ENOREG;
	}

	return eStatus;
}
/****************************************************************************
* 名	  称：eMBRegDiscreteCB
* 功    能：读取离散寄存器，对应功能码有：02 读离散寄存器 eMBFuncReadDiscreteInputs
* 入口参数：pucRegBuffer: 数据缓存区，用于响应主机
*						usAddress: 寄存器地址
*						usNDiscrete: 要读取的寄存器个数
* 出口参数：
* 注	  意：1 区
****************************************************************************/
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    ( void )pucRegBuffer;
    ( void )usAddress;
    ( void )usNDiscrete;
    return MB_ENOREG;
}

// 7、修改mbrtu.c文件，否则modbus从机收到命令后，只会返回一次数据。在函数“eMBRTUSend”中。

//eMBErrorCode
//eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
//{
//    eMBErrorCode    eStatus = MB_ENOERR;
//    USHORT          usCRC16;
//
//    ENTER_CRITICAL_SECTION(  );
//
//    /* Check if the receiver is still in idle state. If not we where to
//     * slow with processing the received frame and the master sent another
//     * frame on the network. We have to abort sending the frame.
//     */
//    if( eRcvState == STATE_RX_IDLE )
//    {
//        /* First byte before the Modbus-PDU is the slave address. */
//        pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
//        usSndBufferCount = 1;
//
//        /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
//        pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
//        usSndBufferCount += usLength;
//
//        /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
//        usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
//        ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
//        ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
//
//        /* Activate the transmitter. */
//        //发送状态转换，在中断中不断发送
//        eSndState = STATE_TX_XMIT;
//
//        //启动第一次发送，这样才可以进入发送完成中断
//        xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
//        pucSndBufferCur++;  /* next byte in sendbuffer. */
//        usSndBufferCount--;
//
//        //使能发送状态，禁止接收状态
//        vMBPortSerialEnable( FALSE, TRUE );
//    }
//    else
//    {
//        eStatus = MB_EIO;
//    }
//    EXIT_CRITICAL_SECTION(  );
//    return eStatus;
//}
//



